<template>
	<ao-cascader :type="parentModel.condition=='aggregate'?'key':parentModel?.$badge" v-model="model.field"
		:show-all-levels="true" :options="_options" @change="handleChange">
	</ao-cascader>

	<taOperator :options="_options" @change="handleOperatorChange" v-model="model" v-if="model.type=='datetime'"
		style="margin-right: 10px;width:180px;">

	</taOperator>

	<el-select @change="handleOperatorChange" v-else :disabled="!model.field" v-model="model.operator"
		style="margin-right: 10px;width: 140px;">
		<template v-if="model.component && model.component.type">
			<el-option v-for="(t, i) in calculation['select']" :key="i" :label="t.label" :value="t.value" />
		</template>
		<template v-else>
			<el-option v-for="(t, i) in calculation[model.type]" :key="i" :label="t.label" :value="t.value" />
		</template>
	</el-select>
	<!--
	<inForm v-model="model.value" :type="model.type" :interval="model.operator" v-if="model.field"></inForm>
	-->
	<template v-if="model.operator">

		<template v-if="~model.operator.indexOf('empty') || ~model.operator.indexOf('exists')">

		</template>

		<template v-else>

			<template v-if="model.component && Object.keys(model.component).length>0">
				<template v-if="model.component.type=='el-select'">
					<el-select v-model="model.value" style="width: 250px;" multiple>
						<el-option v-for="(t, i) in model.component.props.options" :key="i" :label="t.label"
							:value="t.value" />
					</el-select>
				</template>

				<template v-if="model.component.type=='taCascader' || model.component.type=='blCascader'">
					<taCascader @Update:modelValue="(value)=>(model.value = value.map(item => item.id))"
						:params="model.component.props.params" :apiObj="$API.system.custGroup.dictionary"
						v-model="model.component.props.model" style="width: 250px;"></taCascader>
				</template>

				<template v-else-if="model.component.type== 'sc-table-select'">
					<view style="width: 250px;">
						<sc-table-select @Update:modelValue="(value)=>(model.value = value.map(item => item.id))"
							:params="model.component.props.params" v-model="model.component.props.model"
							:apiObj="$API.system.custGroup.dictionary" :table-width="600" multiple clearable
							collapse-tags collapse-tags-tooltip @change="change" :props="model.component.props.props || {
							'label':'name',
	                        'value':'id',
	                        'keyword':'keyword',
						}">
							<template #header="{form, submit}">
								<div style="display: flex;">
									<el-form :inline="true" :model="form">
										<el-form-item>
											<el-input v-model="form.keyword"></el-input>
										</el-form-item>
										<el-form-item>
											<el-button type="primary" @click="submit">查询</el-button>
										</el-form-item>
									</el-form>
									<div style="flex: 1;">
										&nbsp;
									</div>
								</div>
							</template>
							<el-table-column prop="code" label="编码" width="140"></el-table-column>
							<el-table-column prop="name" label="名称"></el-table-column>
							<el-table-column prop="created_at" label="创建时间"></el-table-column>
						</sc-table-select>
					</view>
				</template>

			</template>

			<div v-else-if="model.type == 'string'">
				<template v-if="~model.operator.indexOf('like') || ~model.operator.indexOf('match')">
					<el-input-tag @keydown.native.enter.prevent="handleEnter" @mouseover.stop.prevent=""
						style="width: 250px;" delimiter="," v-model="model.value" placeholder="请输入"
						aria-label="输入后请按回车键确认" clearable />
				</template>
				<template v-else>
					<el-input size="" v-model="model.value"></el-input>
				</template>
			</div>

			<div v-else-if="model.type == 'number' || model.type == 'count'">
				<template v-if="~model.operator.indexOf('between') && model.value">
					<el-input-number size="" v-model="model.value[0]" :min="0"></el-input-number>
					<span style="padding:0px 10px;">~</span>
					<el-input-number size="" v-model="model.value[1]" :min="model.value[0]"></el-input-number>
				</template>
				<template v-else>
					<el-input-number size="" v-model="model.value" :min="0"></el-input-number>
				</template>
			</div>


		</template>

	</template>

	<span style="padding-left: 10px;"
		v-if="model.operator && !(~model.operator.indexOf('empty') || ~model.operator.indexOf('exists'))"></span>

	<div class="showButton" style="opacity: 1;">

		<el-button v-if="model.$debug" type="danger" icon="el-icon-magic-stick" size="small" @click="handleTest">
			测试
		</el-button>

		<template v-if="parentModel.condition!=='aggregate'">
			<el-button type="success" size="small" icon="el-icon-plus" @click="$emit('add-rule', depth)">条件</el-button>
			<el-button v-if="depth<5 && !(parentModel?.$badge=='指标')" type="primary" size="small" icon="el-icon-plus"
				@click="$emit('add-group')">条件组</el-button>
			<el-button style="color:#FFF;" color="#C8A2C8"
				v-if="depth<5 && !(parentModel?.$badge=='指标' || parentModel?.$badge=='维度')" size="small"
				icon="el-icon-plus" @click="$emit('add-aggregate')">
				聚合组
			</el-button>
			<el-button type="warning" size="small" icon="el-icon-document-copy" @click="$emit('copy-rule', depth)"
				title="复制规则">
			</el-button>
			<el-button size="small" class="draggable" icon="el-icon-rank" draggable="true" title="拖拽排序"
				@dragstart="handleDragStart" @dragend="handleDragEnd">
			</el-button>
		</template>

		<template v-if="!((parentModel?.$badge=='指标' || parentModel?.$badge=='维度') && parentModel.rules.length == 1)">
			<el-button type="danger" size="small" icon="el-icon-close" @click="deleteRule"
				style="width: 20px;"></el-button>
		</template>
	</div>

</template>
<script>
	import cal from "./calculationJson.js"
	import inForm from './inForm.vue'
	import blCascader from './components/blCascader.vue'
	import taOperator from './components/taOperator.vue'
	import aoCascader from './components/aoCascader.vue'

	export default {
		inject: ['deleteRuleBy'],
		props: {
			depth: {
				type: Number,
				default: 0
			},
			fieldVal: Object,
			options: Object
		},
		components: {
			inForm,
			blCascader,
			taOperator,
			aoCascader
		},
		data() {
			return {
				calculation: cal.calculation,
				_options: [],
				operatorWatch: {},
				enterCount: 0,
				enterTimer: null
			}
		},
		mounted() {
			this._options = JSON.parse(this.safeStringify(this.options || []));
		},
		watch: {
			'model.operator'(newVal, oldVal) {
				this.operatorWatch = {
					oldVal: oldVal,
					newVal: newVal
				};
			}
		},
		computed: {
			parentModel: {
				get() {
					return this.$parent?.$parent?.model || {};
				}
			},
			model: {
				get() {
					if (~this.fieldVal.operator?.indexOf("like")) {
						if (!Array.isArray(this.fieldVal.value) && this.fieldVal.value) {
							this.fieldVal.value = [this.fieldVal.value];
						}
					}
					return this.fieldVal
				},
				set(value) {
					this.$emit('update:modelValue', value)
				}
			}
		},
		methods: {
			handleTest() {
				let group = JSON.parse(JSON.stringify(this.parentModel))
				let thisModel = JSON.parse(JSON.stringify(this.model))
				thisModel.$debug = false;

				let dsl = {
					condition: "and",
					rules: [
						thisModel,
						group
					]
				};

				this.loading = true
				this.$API.system.custGroup.test.post({
					dsl: dsl
				}).then(res => {
					this.$alert(res.msg, res.code == 0 ? '提示' : '错误', {
						type: res.code == 0 ? 'success' : 'error'
					})
				}).finally(() => {
					this.loading = false
				})

			},
			handleEnter(event) {
				this.enterCount++;
				clearTimeout(this.enterTimer); // 清除之前的定时器

				if (this.enterCount === 3) {
					this.onTripleEnter(); // 触发三次回车回调
					this.enterCount = 0; // 重置计数
				} else {
					// 设置1秒后重置计数器
					this.enterTimer = setTimeout(() => {
						this.enterCount = 0;
					}, 1000);
				}
			},
			onTripleEnter() {
				let {
					field,
					operator
				} = this.model;
				if (field == "客户信息.客户卡号" && operator == "match") {
					this.model.$debug = !this.model.$debug;
					if (this.model.$debug) {
						this.$message.success('开启测试模式！');
					} else {
						this.$message.success('关闭测试模式！');
					}
				}
			},
			deleteRule() {
				if (this.parentModel.condition == 'aggregate') {
					this.$parent.$parent.$emit('delete-group');
				} else {
					this.$emit('delete-rule')
				}
			},
			handleDragStart(event, variable) {
				event.dataTransfer.setData('text/plain', this.safeStringify(this.model));
				event.dataTransfer.effectAllowed = 'copy';
			},
			handleDragEnd(e) {
				if (e.dataTransfer.dropEffect === 'copy') {
					this.deleteRuleBy(this.model.$id);
					this.deleteRuleBy([]);
				}
			},
			safeStringify(obj, indent = 2) {
				let cache = [];
				const retVal = JSON.stringify(
					obj,
					(key, value) =>
					typeof value === "object" && value !== null ?
					cache.includes(value) ?
					undefined :
					cache.push(value) && value :
					value,
					indent
				);
				cache = null;
				return retVal;
			},
			handleOperatorChange(e) {
				this.$nextTick(() => {

					const {
						oldVal,
						newVal
					} = this.operatorWatch;

					const rules = {
						'datediff second': ['>', 'getdate()', '0'],
						'datediff': ['>', 'getdate()', '1'],
						'between datediff': ['past', 1, 'now'],
						'between': [null, null],
						'like': [],
						'match': [],
						'in': [],
						'': null,
					};

					const getTypeByOp = (op) => {
						// 预处理：移除开头的 "not "
						const cleanOp = op.replace(/^not /, '');
						// 用 find 代替 some，直接返回第一个匹配的 key
						const matchedKey = Object.keys(rules).find(key => cleanOp.startsWith(key));
						return matchedKey || ""; // 返回第一个匹配的 key 或空字符串
					};

					const newType = getTypeByOp(newVal);
					const oldType = getTypeByOp(oldVal);

					if (!oldVal || newType !== oldType) {
						this.model.value = rules[newType];
					}
				});
			},
			handleChange(value) {
				if (!value) return
				this.model.operator = ""
				const lastLevelObject = this.findLastLevelObject(this._options, value);
				this.model.field = lastLevelObject.id
				this.model.type = lastLevelObject.type
				this.model.component = lastLevelObject.component
				if (this.model.component.type == 'el-select') {
					this.model.value = []
				} else {
					this.model.value = null
				}
			},
			change(e) {
				console.error(e)
			},

			async generateOptions(params) {
				const response = await this.$API.system.custGroup.dictionary.post(params);
				console.error(response.data)
				return response.data
			},
			findLastLevelObject(options, value) {
				let currentOptions = options;
				for (let i = 0; i < value.length; i++) {
					const currentValue = value[i];
					const foundOption = currentOptions.find(option => option.id === currentValue);
					if (foundOption) {
						if (i === value.length - 1) {
							return foundOption;
						}
						currentOptions = foundOption.children || [];
					}
				}
				return null;
			}
		}
	}
</script>

<style scoped>
	.showButton {
		padding-right: 10px;
	}

	.showButton:hover {
		opacity: 1 !important;
	}

	.draggable:hover {
		background-color: #f4f6f9;
	}
</style>
